/*
 * @Author: funlee
 * @Email: i@funlee.cn
 * @Date: 2018-06-10 13:42:28
 * @Description: 
 * 注意事项 增加初始时间范围[start,end] 如初始默认展示最近一个月，手动计算[start,end] 
 * 当数据个数不足 splitNumber 个 是否还需要时间轴，如果需要展示时间轴，则数据响应的要进行过滤，如果不需要，则需要添加代码限制 renderData = data
 */
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import moment from 'moment';
import echarts from 'echarts';
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      AreaChart: null, // 面积图
      DateChart: null, // 时间轴
      data: [],  // 原始数据
      dateChartData: [], // 时间轴图表数据
      splitNumber: 9,
      renderDataLen: 0, // 用于控制时间轴是否展示,当数量不足 splitNumber 个 时间轴没必要了
    }
  }
  componentDidMount() {
    const AreaChart = echarts.init(this.AreaChart);
    const DateChart = echarts.init(this.DateChart);
    this.setState({
      AreaChart,
      DateChart
    }, () => this.getData()) 

    DateChart.on('dataZoom', (params) => {
      const { start, end } = params;
      this.filterAreaData(start, end)
    })
  }
  getData() {
    // 获取原始数据
    const data = []; // 原始数据 -- Ajax
    let value = Math.random() * 100;
    for (let i = 0; i < 1000; i++) {
      value = value + Math.random() * 21 - 10;
      data.push({
        name: moment().add(i * 2, 'days').format(),
        value: Math.round(value)
      });
    }
    // 获取时间轴图表所需的数据
    const dateChartData = [];  // 时间轴图表所需的数据
    data.forEach(d => {
      const { name,value } = d
      dateChartData.push({
        name,
        value:[name, value]
      })
    })
    this.setState({
      data,
      dateChartData
    }, () => this.renderChart())
  }
  renderChart() {
    this.filterAreaData(); // 先过滤数据在渲染
    this.renderDateChart(); // 时间轴--直接渲染
  }
  filterAreaData(start = 0, end = 100) {
    const { data, dateChartData, splitNumber } = this.state;
    const len = data.length; // 总的数据个数

    const startIndex = start === 100 ? len - 1 : parseInt(len * start / 100, 10); // 起点数据的位置,需要判断是否是 100%
    const endIndex = end === 100 ? len - 1 : parseInt(len * end / 100, 10);   // 终点数据的位置，需要判断是否是 100%

    const renderData = dateChartData.slice(startIndex, endIndex);
    const renderDataLen = endIndex - startIndex;

    const startData = data[startIndex]; // 起点数据，此处时间格式为：YYYY-MM-DD
    const endData = data[endIndex]; // 终点数据，此处时间格式为：YYYY-MM-DD

    const sepYear = moment(endData.name).format('YYYY') - moment(startData.name).format('YYYY'); // 相隔多少年
    const sepMonth = moment(endData.name).format('MM') - moment(startData.name).format('MM'); // 渲染数据都在一年里，相隔多少月
    
    /**
     * 前面的前提都是 数据个数 > splitNumber 的情况
     * 如果年或月有差距， 但是数量不足 splitNumber 个，X 轴应该 全部展示
     */
    if (renderDataLen >= splitNumber && sepYear >= splitNumber) { // 年份相隔大于 splitNumber 年，按年展示，这样不会有重复年份
      this.renderAreaChart(renderData, 'YYYY')
    } else if (renderDataLen >= splitNumber && sepYear < splitNumber && sepYear > 0) { // 相隔年份在 1 ~ splitNumber 年， 这时会出现重复年份所以增加月份展示
      this.renderAreaChart(renderData, 'YYYY-MM')
    } else if (renderDataLen >= splitNumber && sepYear === 0 && sepMonth > splitNumber) { // 在同一年范围内，相隔大于 splitNumber 月，按照月展示，这样不会有重复
      this.renderAreaChart(renderData, 'MM')
    } else if (renderDataLen >= splitNumber && sepYear === 0 && sepMonth <= splitNumber && sepMonth > 0) { // 相隔年份在 1 ~ splitNumber 月， 这时会出现重复月份所以增加日展示
      this.renderAreaChart(renderData, 'MM-DD')
    } else if (sepYear === 0 && sepMonth === 0) { // 在同一个月范围内，不管数量是否足够 splitNumber 个，都按照天展示，不会有重复
      this.renderAreaChart(renderData, 'DD')
    } else { // 即：数量太少，且年或月还有很大的间隔的情况 全部展示
      this.renderAreaChart(renderData, 'YYYY-MM-DD')
    }
  }
  renderAreaChart(data, dateType) {
    const { AreaChart, splitNumber } = this.state;

    const option = {
      grid: {
        bottom: '15%' // 调整底部距离
      },
      tooltip: {
        trigger: 'axis',
        formatter: function(params) {
          const { data:{value} } = params[0];
          return `数量: ${value[1]}<br />时间: ${moment(value[0]).format('YYYY-MM-DD')}`
        },
        axisPointer: {
          snap: false,
          lineStyle: {
            color: '#6adbff',
            width: 2
          }
        },
      },
      xAxis: {
        type: 'time',
        splitNumber,
        axisLine: {
          lineStyle: {
            color: '#fff'
          }
        },
        axisTick: {
          lineStyle: {
            color: '#fff'
          }
        },
        splitLine: {
          show: false
        },
        axisLabel: {
          color: '#fff',
          fontSize: 16,
          formatter: function (value) {
            switch(dateType) {
              case 'YYYY-MM-DD':
                return `${moment(value).format('YYYY-MM-DD')}`
              case 'YYYY':
                return `${moment(value).format('YYYY')}年`
              case 'YYYY-MM':
                return `${moment(value).format('YYYY')}年${moment(value).format('MM')}月`
              case 'MM':
                return `${moment(value).format('MM')}月`
              case 'MM-DD':
                return `${moment(value).format('MM')}月${moment(value).format('DD')}日`
              case 'DD':
                return `${moment(value).format('DD')}日`
              default:
                return `${moment(value).format('YYYY-MM-DD')}`
            }
          }
        }
      },
      yAxis: {
        type: 'value',
        min: 0,
        axisLine: {
          lineStyle: {
            color: '#fff'
          }
        },
        axisTick: {
          show: false
        },
        splitLine: {
          show: false
        },
        axisLabel: {
          color: '#fff',
          fontSize: 16
        }
      },
      series: [{
        name: '信息发布趋势',
        type: 'line',
        smooth: true,
        symbol: 'none',
        sampling: 'average',
        showSymbol: false,
        hoverAnimation: false,
        lineStyle: {
          color: '#47b2dd'
        },
        areaStyle: {
          normal: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
              offset: 0,
              color: '#144294' // 上部
            }, {
              offset: 1,
              color: '#102d67' // 底部
            }])
          }
        },
        data: data
      }]
    }; 
    AreaChart.setOption(option);
  }
  renderDateChart() {
    const { dateChartData, DateChart } = this.state;
    const option = {
      xAxis: {
        type: 'time',
        show: false,
      },
      yAxis: {
        show: false
      },
      dataZoom: [{
        type: 'inside'
      },{
        backgroundColor: 'rgba(33,51,103,.1)',
        dataBackground:{
          lineStyle: {
            color: 'rgba(17,54,122,0)'
          },
          areaStyle: {
            color: {
              type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [{
                  offset: 0,
                  color: 'rgba(57,101,155,.8)' // 0% 处的颜色
                }, {
                  offset: 1,
                  color: 'rgba(32,51,100,.8)' // 100% 处的颜色
                }]
            }
          }
        },
        fillerColor: 'rgba(33,51,103,.3)', // 选中范围的填充颜色
        handleStyle: { 
          color: '#0090ff',
        },
        showDetail: true,
        realtime: false,
        labelFormatter: function(value){
          return `${moment(value).format('YYYY-MM-DD')}`
        },
        textStyle: { // 显示选中的时间范围
          color: '#fff',
          fontSize: 14
        }
      }],
      series: [{
        type: 'line',
        showSymbol: false,
        hoverAnimation: false,
        lineStyle:{
          color: 'rgba(0,0,0,0)'
        },
        data: dateChartData
      }]
    }; 
    DateChart.setOption(option);
  }
  
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <div className="chart" ref={e => this.AreaChart = e} style={{width: 1400, height: 600, margin: '20px auto 0'}} />
        <div className="date-chart" ref={e => this.DateChart = e} style={{width: 1400, height: 50}} />
      </div>
    );
  }
}

export default App;
